const router = require('express').Router();
const XML2JS = require('xml2js');
const WXMsgCrypto = require('./utils/wxcrypto');
const { generateMessage } = require('./utils/message');
const { getAccessToken } = require('./utils/request');

const wxMsgCrypto = new WXMsgCrypto(
  process.env.TOKEN,
  process.env.ENCODINGAESKEY,
  process.env.APPID
);
const xmlParser = new XML2JS.Parser();

router.get('/health', (req, res) => {
  res.send('success');
});

const checkSignature = (signature, timestamp, nonce) => {
  let tempSignature = wxMsgCrypto.getSignature(timestamp, nonce) || '';
  console.log('tempSignature', tempSignature);
  console.log('signature', signature);
  return tempSignature == signature;
};

router.get('/', (req, res) => {
  try {
    const { signature, timestamp, nonce, echostr } = req.query;
    if (checkSignature(signature, timestamp, nonce)) res.send(echostr);
    else res.send('signature invalid');
  } catch (error) {
    console.log(error);
    res.send();
  }
});

router.post('/', async (req, res) => {
  try {
    const { timestamp, nonce } = req.query;
    const { xml } = req.body;
    const encryptData = xml.Encrypt[0];
    const { message, appId } = wxMsgCrypto.decrypt(encryptData);
    if (appId !== process.env.APPID) throw new Error('appid invalid');
    let { xml: parsedXML } = await xmlParser.parseStringPromise(message);
    // 接收方账号（本微信公众号）
    const toUserName = parsedXML.ToUserName && parsedXML.ToUserName[0];
    // 发送方帐号（一个OpenID）
    const fromUserName = parsedXML.FromUserName && parsedXML.FromUserName[0];
    // 消息类型: 事件event 文本text
    const msgType = parsedXML.MsgType && parsedXML.MsgType[0];
    // 文本内容
    const content = parsedXML.Content && parsedXML.Content[0];
    // 文本内容
    const event = parsedXML.Event && parsedXML.Event[0];

    // 接收订阅的消息
    let plain = await generateMessage({
      fromUserName,
      toUserName,
      timestamp,
      event,
      msgType,
      content,
    });
    // 1. 先对原文进行加密
    const encrypt = wxMsgCrypto.encrypt(plain);
    // 2. 时间戳、随机值、加密密文进行签名
    const signatureNew = wxMsgCrypto.getSignature(timestamp, nonce, encrypt);
    // 3. 拼接返回XML
    res.send(`<xml>
<Encrypt><![CDATA[${encrypt}]]></Encrypt>
<MsgSignature><![CDATA[${signatureNew}]]></MsgSignature>
<TimeStamp>${timestamp}</TimeStamp>
<Nonce><![CDATA[${nonce}]]></Nonce>
</xml>`);
  } catch (error) {
    console.log(error);
    res.send('success');
  }
});

router.post('/signature', (req, res) => {
  try {
    let { url } = req.body;
    url = decodeURIComponent(url);
    const timestamp = new Date().getTime() / 1000;
    const nonce = Math.random().toString(36).slice(-8);
    let signature = wxMsgCrypto.getSignature(timestamp, nonce, url);
    res.send({
      status: 'success',
      signature,
      appId: process.env.APPID,
      timestamp,
      nonce,
    });
  } catch (error) {
    res.send();
  }
});

router.post('/getAccessToken', async (req, res) => {
  try {
    const accessToken = await getAccessToken();
    res.send({ accessToken });
  } catch (error) {
    res.send();
  }
});

module.exports = router;
